// api
import{ batchBalanceTask, getTaskBalanceCount, getTaskBalanceFieldInfo, getTaskBalanceList, getTaskBalanceListInitData, getTaskBalancePrice, getCurrentAllTaskTypeList } from '@src/api/TaskApi'
/* business */
import BizListViewTask from '@src/component/business/BizListView/Impl/BizListViewTask/BizListViewTask.tsx'
/* components */
import BizFormDialog from '@src/component/business/BizFormDialog/BizFormDialog.tsx'
import formatColumn from 'packages/BaseTableCell/formatColumn'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import StorageKeyEnum from '@model/enum/StorageKeyEnum'
import SubscriptionModuleEnum from '@model/enum/SubscriptionModuleEnum'
import BalanceConfirmEnum from '@model/enum/BalanceConfirmEnum'
import { FieldTypeMappingEnum, LogisticsFieldNameMappingEnum } from '@model/enum/FieldMappingEnum'
import AuthEnum from '@model/enum/AuthEnum'
import { pageTaskAuditList } from 'pub-bbx-global/pageType/dist';
/* util */
import AuthUtil from '@src/util/auth'
import { sessionStorageGet, sessionStorageRemove } from '@src/util/storageV2'
import i18n from '@src/locales'
/* entity */
import { PlanTask } from '@model/entity/PlanTask'
import Field from '@model/entity/Field'
import { checkButtonDisplayed } from '@src/util/dom'


/* model */
import { 
  getBatchTaskBalanceResult, 
  getTaskBalanceCountResult, 
  getTaskBalanceInitDataResult, 
  getTaskBalancePriceResult, 
  TaskBalanceCountData 
} from '@model/param/out/Task'
import { TaskExportModel, TaskSearchListModel } from '@model/param/in/Task'
import { allExport, getColumnFields, getAdvancedFields } from '@src/modules/task/taskTypes/balance/fields'
import { BATCH_BALANCE_SUCCESS_MESSAGE, NOT_OPEN_BALANCE_MASSAGE } from '@src/model/const/Alert'
import { TaskExportGroupChecked } from '@src/component/business/BizListView/Impl/BizListViewTask/BizListViewTaskInterface'
import Column from '@model/types/Column'
import { TaskExportBalanceFields, TaskBalanceReceiptExportFields, TaskExportGroupTextEnum, TaskExportGroupValueEnum } from '@src/component/business/BizListView/Impl/BizListViewTask/BizListViewTaskModel'
import { commonUseItemType } from '@src/component/AdvancedSearch/advancedSearch'
/* scss */
import '@src/modules/task/taskTypes/balance/TaskBalanceList.scss'
/* service */
import { isAttachmentFiled, isSystemFiled, isPlanTimeField, isTaskNoField, getFieldName, isNotSupportedDisplayField } from '@service/FieldService'
/* vue */
import { Component, Ref } from 'vue-property-decorator'
import { CreateElement } from 'vue'
import { VNode } from 'vue'
/* util */
import Platform from '@src/util/platform'
import LogUtil from '@src/util/log.ts'
import { fmt_number, fmt_number_fixed2 } from '@src/filter/fmt'
import { parseObject, stringify } from '@src/util/lang/object'
import EsSort from '@model/types/EsSort'
import EsTaskSearchInput from '@model/types/EsTaskSearchInput'
import { hasOwn } from '@src/util/lang/object'
import { FlagConvertMap, TaskApproveConvertMap, TaskOnceConvertMap } from '@src/modules/task/model/TaskConvertMap'
import { isArray } from '@src/util/type'
import TaskStateEnum from '@model/enum/TaskStateEnum'
import Log from '@src/util/log.ts'
import * as _ from 'lodash';

/* export & import */
import { taskBalanceListExport } from '@src/api/Export';
// import { eventListImport_1, eventListImportTem_1 } from '@src/api/Import';
import { storageSet, storageGet } from '@src/util/storageV2';
interface City {
  cusCountry?: string
  cusProvince?: string
  cusCity?: string
  cusDist?: string
}

function getUserIdsForSearch(user: any, params: Record<string, any>, userKey: string): any {
  let users: any[] = params[userKey]
  let isUserArray = isArray(users) 
  
  if (user && isUserArray) return users
  
  return (
    user
      ? isUserArray
        ? users.push(user) 
        : []
      : isUserArray
        ? users
        : []
  )
}

/* 工单 曾.. 字段 的数据转换 */
function taskOnceFieldValueConvert(data: any): number | null {
  if (hasOwn(TaskOnceConvertMap, data)) {
    return TaskOnceConvertMap[data]
  }
  
  return data
}

/* 工单 审批状态 的数据转换 */
function taskApproveValueConvert(data: any): number | null {
  if (hasOwn(TaskApproveConvertMap, data)) {
    return TaskApproveConvertMap[data]
  }
  
  return data
}

const BalanceCountMap: Record<string, Record<string, string>> = {
  // 近30天已结算工单
  balanceCountNearlyOneMonth: { backgroundColor: 'rgb(249, 184, 84)', icon: 'icon-fdn-serviceContent' },
  // 近30天已结算费用
  balanceTotalNearlyOneMonth: { backgroundColor: 'brown', icon: 'icon-huafei' },
  // 未结算工单数量
  unBalanceCount: { backgroundColor: 'rgb(51, 176, 255)', icon: 'icon-fdn-serviceContent' },
  // 未结算费用
  unBalanceCost: { backgroundColor: 'rgb(137, 213, 121)', icon: 'icon-huafei' }
}

@Component({ 
  name: ComponentNameEnum.TaskBalanceList
})
export default class TaskBalanceList extends BizListViewTask<PlanTask> {
  
  @Ref() readonly BizFormDiaLogComponent!: BizFormDialog
  
  /* 全部搜索参数 */
  private allSearchParams: Record<string, any> = {}
  /* 高级搜索字段缓存数据 */
  public advancedSearchFieldStorageKey: StorageKeyEnum = StorageKeyEnum.TaskBalanceListSearchFields
  /* 是否结算  */
  private balanceConfirm: BalanceConfirmEnum = BalanceConfirmEnum.BalanceNotConfirm
  /* 当前条件结算总金额数量 */
  private balancePrice: string = ''
  /* 当前条件结算总金额货币单位 */
  private balancePriceCurrency: string = ''
  /* 结算自定义字段列表 */
  private balanceFields: Field[] = []
  /* 列数据 */
  public columns: Column[] = this.getColumnFields(this) as Column[]
  /* 初始数据 */
  public initData: getTaskBalanceInitDataResult = {
    balanceOn: true,
    hasSub: false,
    taskTypeList: []
  }
  /* 无权限提示文字 */
  private noPermissionText: string = NOT_OPEN_BALANCE_MASSAGE
  /* 选择列 缓存键名 默认未结算 */
  public selectColumnStorageKey: StorageKeyEnum = StorageKeyEnum.TaskBalanceTableColumnsNot
  /* pageSize 缓存键名 */
  public pageSizeStorageKey: StorageKeyEnum = StorageKeyEnum.TaskBalancePageSize
  /* 工单结算列表统计 */
  private taskBalanceCount: TaskBalanceCountData | null = null
  /* 导出地址url */
  public exportActionUrl: string = taskBalanceListExport
  /* 支付方式 */
  public payMethod = [
    { label: i18n.t('order.setting.online'), value: 1, count: 11 },
    { label: i18n.t('common.member.quotaSettlement'), value: 2, count: 12 },
  ]
  /* 当前支付方式 */
  public currentPayMethod = 0
  
  /** 
   * @description 是否为未结算选项
  */
  get isNoBalanceRadio() {
    return this.balanceConfirm === BalanceConfirmEnum.BalanceNotConfirm
  }
  
  /**
   * @description: 审核结算列表是否开启
   * @return {Boolean} 审核结算开启状态
   */  
  get balanceOn(): boolean {
    return Boolean(this.initData.balanceOn)
  }
  /**
   * @description: 是否有批量结算权限
   * @return {Boolean} 
   */  
  get canBalanceBatch(): boolean {
    return AuthUtil.hasAuth(this.auth, AuthEnum.TASK_BATCH_AUDIT)
  }
  
  /**
   * @description: 构建导出列
   * @return {void}
   */  
  public buildExportColumns(): void {
    this.exportTaskColumns = [
      // 工单字段字段
      {
        label: TaskExportGroupTextEnum.Task,
        value: TaskExportGroupValueEnum.Task,
        columns: this.buildExportColumnsOfTaskFields()
      },
      // 回执字段
      {
        label: TaskExportGroupTextEnum.TaskReceipt,
        value: TaskExportGroupValueEnum.TaskReceipt,
        columns: this.buildExportColumnsOfTaskReceiptFields()
      },
      // 结算字段
      {
        label: TaskExportGroupTextEnum.Balance,
        value: TaskExportGroupValueEnum.Balance,
        columns: this.buildExportColumnsOfTaskBalanceFields()
      },
      // 系统字段
      {
        label: TaskExportGroupTextEnum.System,
        value: TaskExportGroupValueEnum.System,
        columns: allExport.map((field: any) => {
          field.export = true
          field.label = field.displayName || ''
          return field
        })
      },
      // 附加卡片字段
      ...this.buildExportColumnsOfTaskCardFields()
    ]
  }
  
  /**
   * @description: 构建给导出列使用的工单结算字段列表
   * @return {Field[]} 给导出列使用的工单结算字段列表
   */
  public buildExportColumnsOfTaskBalanceFields(): Field[] {
    // 结算字段列表
    const taskExportBalanceFields: Field[] = (
      // 默认结算字段 拼接 自定义 结算字段列表
      TaskExportBalanceFields.concat(this.balanceFields).slice()
    )
    
    return (
      taskExportBalanceFields.map(field => {
        field.export = true
        field.label = field.displayName
        field.exportAlias = field.fieldName
        return field
      })
    )
  }
  
  /**
   * @description: 构建给导出列使用的工单回执字段列表
   * @return {Field[]} 给导出列使用的工单回执字段列表
   */
  public buildExportColumnsOfTaskReceiptFields(): Field[] {
    // 当前工单类型的工单回执字段列表
    const CurrentTaskReceiptFields: Field[] = this.taskReceiptFields.slice()
    
    // 导出的工单回执字段列表
    const ExportTaskReceiptFields: Field[] = [
      ...TaskBalanceReceiptExportFields.slice(), // 审核结算没有费用信息
      ...CurrentTaskReceiptFields.filter((taskReceiptField: Field) => {
        // 过滤系统字段和附件类型字段 关联字段
        return (
          !isSystemFiled(taskReceiptField) 
          && taskReceiptField.formType !== FieldTypeMappingEnum.Attachment
          && taskReceiptField.formType !== FieldTypeMappingEnum.RelatedForm
        )
      })
    ]
    ExportTaskReceiptFields.forEach((item) => {
      if(item.formType === 'logistics'){
        if(item.fieldName.indexOf(LogisticsFieldNameMappingEnum.LogisticsNo) > -1){
          item.label = i18n.t('common.base.logisticsNo') as string
        }
    
         if(item.fieldName.indexOf(LogisticsFieldNameMappingEnum.LogisticsCompany) > -1){
          item.label = i18n.t('common.base.logisticsCompany') as string
        }
      }
    })
    
    return (
      ExportTaskReceiptFields.map(field => {
        field.export = true
        return field
      })
    )
  }
  
  /**
   * @description 构建导出参数
   * @return {TaskExportModel} 导出参数
   */
  public buildExportParams(checkedMap: TaskExportGroupChecked, ids: string[], exportOneRow?: boolean): TaskExportModel {
    let defaultExportParams: TaskExportModel = this.buildDefaultExportParams(checkedMap, ids, exportOneRow)
    let exportSearchModel = parseObject(defaultExportParams.exportSearchModel, {})
    
    exportSearchModel = {
      ...exportSearchModel,
      balanceConfirm: this.balanceConfirm
    }
    
    defaultExportParams.exportSearchModel = stringify(exportSearchModel)
    
    return defaultExportParams
  }


  /**
   * @description: 初始化工单类型所有字段
   * 工单类型变化之后的事件
   * 1. 获取工单类型字段
   * 2. 获取工单类型回执字段
   * 3. 获取工单类型附加卡片信息
   * 4. 获取用户开启的配置节点 以及工单搜索范围 和 异常原因字段值
   * 5. 构建高级搜索列
   * 6. 构建导出列
   * @return {void}
   */  
   public async initializeTaskTypeAllFields(): Promise<void> {
    // 初始化之前需要reset回执字段，否则fetchTaskFields后onTaskFieldsChangedHandler时审核结算的getColumnFields方法获取的回执字段还是旧值
    this.taskReceiptFields = []

    // 获取工单类型字段
    await this.fetchTaskFields()
    // 获取工单类型回执字段
    await this.fetchTaskReceiptFields()
    // 获取工单类型附加卡片信息
    await this.fetchTaskCardFields()
    // 获取用户开启的配置节点 以及工单搜索范围 和 异常原因字段值
    await this.fetchTurnOnTaskExceptionNodeInfo()
    // 构建高级搜索列
    this.buildAdvancedColumns()
    // 构建导出列
    this.buildExportColumns()
    // 构建选择列
    this.dealWithSelectColumnStorageKey(this.balanceConfirm)
  }
  
  /**
   * @description: 获取高级搜索字段列表
   * @param {BizListViewTask} vm 当前实例
   * @return {Field[]} 高级搜索字段列表
   */  
  public getAdvancedFields(vm: BizListViewTask): Field[] {
    return [...getAdvancedFields(vm).filter(field => field.show), ...this.buildAdvancedColumnsWithBalance()]
  }
  
  /**
   * @description 构建高级搜索列
   */
  public buildAdvancedColumns() {
    this.advanceSearchColumns = [
      ...this.getAdvancedFields(this),
      ...this.buildAdvancedColumnsWithBalance()
    ]
  }
  
  public buildAdvancedColumnsWithBalance(): Field[] {
    return (
      this.balanceFields
        .filter(balanceField => {
          // 过滤非系统字段和附件字段和工单编号字段
          return !isSystemFiled(balanceField) && !isAttachmentFiled(balanceField) && !isTaskNoField(balanceField)
        })
        .map(balanceField => {
          if (isPlanTimeField(balanceField)) {
            balanceField.formType = FieldTypeMappingEnum.DateTime
            balanceField.isNull = 1
          }
          return balanceField
        })
    )
  }
  
  /**
   * @description: 获取表格列字段列表
   * @param {BizListViewTask} vm 当前实例
   * @return {Field[]} 表格列字段列表
   */  
  public getColumnFields(vm: BizListViewTask): Field[] {
    const TaskBalanceFields = this.balanceFields ? this.balanceFields.filter(balanceField => !isAttachmentFiled(balanceField)) : []
    const TaskReceiptFields = this.taskReceiptFields ? this.taskReceiptFields.filter(taskReceiptField => {
        // 是否为系统字段
        const isSystem = isSystemFiled(taskReceiptField)
        // 是否为不支持显示的字段
        const isNotSupportedDisplay = isNotSupportedDisplayField(taskReceiptField)
        
        return !isSystem && !isNotSupportedDisplay
    }) : []
    
    return getColumnFields(vm).concat(TaskBalanceFields).concat(TaskReceiptFields)
  }
  
  /** 
   * @description 获取属性
  */
  public getAttributes() {
    const classNames: string[] = [ComponentNameEnum.TaskBalanceList, 'common-list-container__v2']
    
    return {
      class: classNames,
      directives: [
        // {
        //   name: 'loading',
        //   value: this.loading
        // }
      ]
    }
  }
  
  public fetchTableListData() {
    const params = {
      ...this.searchParams,
      ...this.advancedSearchModel,
      balanceConfirm: this.balanceConfirm
    }
    
    this.allSearchParams = params

    this.fetchTaskBalancePrice()
    this.fetchTaskList(params, getTaskBalanceList)
  }

  /** 
   * @description 根据 现有的搜索参数 构建搜索参数
   * 都是抄的之前的
  */
    public buildSearchParamsWithSearchParams(params: TaskSearchListModel, mySearchData: {
      createUser?: string,
      executor?: string,
      synergyId?: string
    }) {
        // 排序条件
        const sorts: EsSort[] = this.buildSortsForSearch(params)
        // 地址数据
        const city: City = this.buildCityForSearch(params)
        const { cusCountry = '', cusProvince = '', cusCity = '', cusDist = '' } = city
        // 系统字段查询条件
        const { systemConditions = [] } = params
        // 自定义字段查询条件
        const conditions = params.conditions || []
        // 审核结算的自定义字段查询条件
        const balanceConditions = params.balanceConditions || []
        // 工单 各流程 时间数据
        const {
          acceptTimeStart, acceptTimeEnd, allotTimeStart, allotTimeEnd, balanceTimeStart, balanceTimeEnd,
          closeTimeStart, closeTimeEnd, completeTimeStart, completeTimeEnd, createTimeStart, createTimeEnd,
          planTimeStart, planTimeEnd, reviewTimeStart, reviewTimeEnd, startTimeStart, startTimeEnd,
          updateTimeStart, updateTimeEnd, planStartTimeStart, planStartTimeEnd, planEndTimeStart, planEndTimeEnd
        } = this.buildTimeForSearch(params)
        
        // 曾转派
        let onceReallot: number | null = taskOnceFieldValueConvert(params.onceReallot)
        // 曾打印
        let oncePrinted: number | null = taskOnceFieldValueConvert(params.oncePrinted)
        // 是否审批中
        let inApprove: number | null = taskApproveValueConvert(params.inApprove)
        
        // TODO: refactoring
        const SearchParams: EsTaskSearchInput = {
            cusCountry,
            cusProvince,
            cusCity,
            cusDist,
            
            conditions: [...conditions],
            balanceConditions: [...balanceConditions],
            
            customerId: params.customerId,
            customerLinkman: params.tlmName || '',
            cusAddress: params.cusAddress,
            productId: params.productId,
            description: params.description,
            
            createTimeStart,
            createTimeEnd,
            planTimeStart,
            planTimeEnd,
            allotTimeStart,
            allotTimeEnd,
            acceptTimeStart,
            acceptTimeEnd,
            startTimeStart,
            startTimeEnd,
            completeTimeStart,
            completeTimeEnd,
            updateTimeStart,
            updateTimeEnd,
            reviewTimeStart,
            reviewTimeEnd,
            balanceTimeStart,
            balanceTimeEnd,
            closeTimeStart,
            closeTimeEnd,
            planStartTimeStart,
            planStartTimeEnd, 
            planEndTimeStart,
            planEndTimeEnd,
            
            balanceUser: params.balanceUser,
            reviewUser: params.reviewUser,
            degree: params.degree,
            
            onceReallot,
            oncePrinted,
            inApprove,
            
            sorts,
            
            templateName: params.templateName,
            keyword: params.keyword,
            page: params.page,
            pageSize: params.pageSize,
            templateId: this.currentTaskType?.id,
            // payMethod: this.currentPayMethod,
            
            /* start 以下是支持多选的 */
            serviceTypes: params.serviceTypes,
            serviceContents: params.serviceContents,
            levels: params.levels,
            
            searchStateList: params.states && params.states.map(stateName => TaskStateEnum.getValue(stateName)),
            allotTypes: this.getAllotTypesForSearch(params.allotTypeStrs),
            flags: params.onceExceptions && params.onceExceptions.map(exception => FlagConvertMap[exception]).filter(exception => Boolean(exception)),
            
            createUserIds: this.getUserIdsForSearch(params.createUser) || getUserIdsForSearch(mySearchData.createUser, params, 'createUser'),
            executorUserIds: this.getUserIdsForSearch(params.executor) || getUserIdsForSearch(mySearchData.executor, params, 'executor'),
            synergyUserIds: this.getUserIdsForSearch(params.synergyId) || getUserIdsForSearch(mySearchData.synergyId, params, 'synergyId'),
            allotUserIds: getUserIdsForSearch(null, params, 'allotUser'),
            
            payTypes: params.paymentMethods,
            searchTagIds: params.tags && params.tags.map(({ id }) => id),
            /* end 以上是支持多选的 */
            
            systemConditions
        }
        
        // 工单搜索分类型
        if (this.keywordSelect) {
          SearchParams.searchCondition = this.keywordSelect
        }
        
        this.searchParams = { ...this.searchParams, ...SearchParams }
        
        Log.info(this.searchParams, 'searchParams', this.buildSearchParamsWithSearchParams.name)
    }
  
  /**
   * @description: 获取初始化数据
   * @return {Promise<void>}
   */  
  public async fetchInitData(): Promise<void> {
    this.loading = true
    
    return (
      getTaskBalanceListInitData()
        .then(async (result: getTaskBalanceInitDataResult) => {
          this.initData = result || {}
          this.taskTypes = this.initData?.taskTypeList || []
          this.auth = result?.authorities || {}
          this.paymentConfig = result?.paymentConfig || null
        })
        .catch(err => {
          console.error(err)
        })
    )
  }
  
  /**
   * @description: 获取结算自定义字段数据
   * @return {Promise<void>}
   */  
  private fetchBalanceFieldInfo(): Promise<void> {
    return (
      getTaskBalanceFieldInfo()
        .then(result => {
          const openUserDefinedBalance = this.initData.taskConfig?.taskBalanceConfig?.openUserDefinedBalance; // 是否启用工单自定义结算字段
          const balanceFields = openUserDefinedBalance ? result || [] : [];
          // 给结算自定义字段一个标识符，用于高级搜索的时候判断是否是结算自定义字段
          balanceFields.forEach(item => {
            item.isBalanceField = true;
          })
          this.balanceFields = balanceFields.filter((field:any) => field.setting.isOpen);
        })
    )
  }
  
  /**
   * @description: 获取工单结算列表统计
   * @return {void}
   */  
  private fetchTaskBalanceCount() {
    getTaskBalanceCount()
      .then((data: getTaskBalanceCountResult) => {
        this.taskBalanceCount = data?.result || {}
      }).catch(err => {
        LogUtil.error(err, this.fetchTaskBalanceCount.name)
      })
  }
  
  /**
   * @description: 获取工单结算金额统计
   * @return {void}
   */  
  private fetchTaskBalancePrice() {
    const params = this.allSearchParams
    
    getTaskBalancePrice(params)
      .then((data: getTaskBalancePriceResult) => {
        this.balancePrice = data?.result.totalPrice
        this.balancePriceCurrency = data?.result.currency || 'CNY'
      }).catch(err => {
        LogUtil.error(err, this.fetchTaskBalancePrice.name)
      })
  }
  
  /**
   * @description 批量结算工单提交事件
   * @return {void}
   */  
  private fetchBatchBalanceTaskSubmit(balanceFormData: Record<string, any>) {
    const packFormData = this.pack(balanceFormData)
    const params = {
      ...packFormData,
      ids: this.selectedIds.join(',')
    }
    if(this.BizFormDiaLogComponent) this.BizFormDiaLogComponent.pending = true
    batchBalanceTask(params)
      .then((result: getBatchTaskBalanceResult) => {
        const isSuccess = result?.succ
        // 失败
        if (!isSuccess) {
          return Platform.alert(result.message)
        }
        
        // 成功提示
        Platform.alert(result.message)
        // 关闭批量结算弹窗
        this.BizFormDiaLogComponent?.outsideClose()
        this.refresh()
      })
      .finally(() => {
        if(this.BizFormDiaLogComponent) this.BizFormDiaLogComponent.pending = false
      })
  }

  // 将数据打包成服务器可接收的数据
  private pack(form: Record<string, any>) {
    let data:any = {}
    let attribute:any = {}
    let attachment:any = {}
    
    this.balanceFields.forEach(field => {
      if(field.formType == 'attachment') {
        attachment = form[field.fieldName];
      } else {
        attribute[field.fieldName] = form[field.fieldName];
      }
    })

    // 要对attachment校验一下 空对象foreach会报错
    Object.keys(attachment).length > 0 && attachment.forEach((item: any, index: any) => {
      data[`balanceAttachments[${index}]`] = item
    })
    
    data.balanceAttributes = attribute;
    return data;
  }
  
  /**
   * @description: 结算状态变化事件
   * @param {BalanceConfirmEnum} value
   * @return {void}
   */  
  private onBalanceConfirmChangedHandler(value: BalanceConfirmEnum | any): void {
    // 读取对应缓存key 缓存的选择列配置 并render
    this.dealWithSelectColumnStorageKey(value)
    
    this.balanceConfirm = value
    this.searchParams.pageNum = 1
    this.search()
    this.fetchTaskBalancePrice()
  }
  
  /**
   * @description: 根据结算状态变化改变审核结算selectColumnStorageKey，获取columns配置并且render表格
   * @param {BalanceConfirmEnum} value
   * @return {void}
   */  
  private dealWithSelectColumnStorageKey(value: BalanceConfirmEnum): void {
    // 不同tab赋值不同的缓存key
    if(value !== '') {
      this.selectColumnStorageKey = value ? StorageKeyEnum.TaskBalanceTableColumnsDone : StorageKeyEnum.TaskBalanceTableColumnsNot
    } else {
      this.selectColumnStorageKey = StorageKeyEnum.TaskBalanceTableColumnsAll
    }
    
    // 构建列数据
    this.columns = [
      ...this.taskFields.filter(field => {
        // 是否为系统字段
        const isSystem = isSystemFiled(field)
        // 是否为不支持显示的字段
        const isNotSupportedDisplay = isNotSupportedDisplayField(field)
        
        return !isSystem && !isNotSupportedDisplay
      }),
      ...this.getColumnFields(this)
    ].map(field => {
      return {
        ...formatColumn(field),
        field: getFieldName(field)
      }
    })
    
    // 合并本地缓存列数据至当前实例的列数据
    this.mergeLocalStorageColumnsToColumns()
  }
  
  /**
   * @description: 打开批量结算工单弹窗
   * @return {void}
   */  
  private openBalanceDialog(): void {
    const openUserDefinedBalance = this.initData.taskConfig?.taskBalanceConfig?.openUserDefinedBalance; // 是否启用工单自定义结算字段
    if(openUserDefinedBalance && this.balanceFields.length) {
      const validated = this.selectedTaskDataValidate()
      if (!validated) return
      
      this.BizFormDiaLogComponent?.outsideShow()
    } else {
      this.$confirm(i18n.t('task.tip.settlementTip10') as string, i18n.t('common.base.toast') as string, {
        confirmButtonText: i18n.t('common.base.makeSure') as string,
        cancelButtonText: i18n.t('common.base.cancel') as string,
        type: 'warning'
      }).then(()=>{
        this.fetchBatchBalanceTaskSubmit({})
      }).catch(()=>{})
    }
  }
  
  public outsideFetchBatchBalanceTaskSubmit(balanceFormData: Record<string, any>) {
    this.fetchBatchBalanceTaskSubmit(balanceFormData)
  }
  
  /**
   * @description: 渲染工单结算金额
   * @return {VNode}
   */  
  private renderBalancePriceBlock(): VNode {
    return (
      <div class="flex-1">
        {i18n.t('task.taskTypes.balance.currentTotal')}： <span>{ fmt_number_fixed2(fmt_number(this.balancePrice, '--'), this.balancePriceCurrency) }</span>
      </div>
    )
  }
  
  /**
   * @description: 渲染工单结算单选框组
   * @return {VNode}
   */  
  private renderBalanceConfirmRadioGroup(): VNode {
    return (
      <el-radio-group 
        value={this.balanceConfirm} 
        onInput={(value: BalanceConfirmEnum) => this.onBalanceConfirmChangedHandler(value)}
        class="mr_12"
      >
        <el-radio-button label={BalanceConfirmEnum.All}>{i18n.t('common.base.all')}</el-radio-button>
        <el-radio-button label={BalanceConfirmEnum.BalanceConfirm}>{i18n.t('common.task.type.costed')}</el-radio-button>
        <el-radio-button label={BalanceConfirmEnum.BalanceNotConfirm}>{i18n.t('task.detail.components.unSettle')}</el-radio-button>
      </el-radio-group>
    )
  }
  
  /**
   * @description: 渲染订阅按钮
   * @return {VNode}
   */  
  private renderSubscriptionButton(): VNode {
    return (
      <subscription-button 
        class="cur-point"
        module={SubscriptionModuleEnum.TaskBalance}
        subscribed={this.initData?.hasSub}
        tooltipContent={i18n.t('task.tip.subscribeTaskTip')}
        onChange={(value: boolean) => this.initData.hasSub = value}
      >
      </subscription-button>
    )
  }
  
  /**
   * @description: 渲染批量结算按钮
   * @return {VNode}
   */  
  private renderBatchBalanceButton(): VNode {
    return (
      <permission auth={this.isNoBalanceRadio && this.canBalanceBatch}>
        <el-button type='primary' onClick={() => this.openBalanceDialog()}>
          {i18n.t('task.taskTypes.balance.batchBalance')}
        </el-button>
      </permission>
    )
  }
  
  /**
   * @description 渲染工单结算弹窗组件
   * @return {VNode}
   */  
  private renderTaskBalanceDialogComponent() {
    return (
      <biz-form-dialog
        ref='BizFormDiaLogComponent'
        buttonText={i18n.t('task.taskTypes.balance.batchBalance')}
        title={i18n.t('task.auditSettle')}
        // footerTip={'结算后，可用额度值将自动增加该笔结算金额'}
        fields={this.balanceFields}
        submitFunction={(balanceFormData: Record<string, any>) => this.outsideFetchBatchBalanceTaskSubmit(balanceFormData)}
      >
      </biz-form-dialog>
    )
  }
  public packUp = true;
  /**
   * @description: 渲染头部容器
   * @return {VNode}
   */ 
  public renderHeaderContainer(): VNode {
    // const allConut = this.payMethod?.reduce((pre, cur) => pre + cur.count, 0) || 0;

    return (
    <div ref="tableHeaderContainer" class='header-container'>
      <div class='common-list-header__v2'>
        { this.renderBalancePriceBlock() }
        <div class="flex-x">
          { this.renderSearchContainer() }
          { this.renderAdvancedSearchButton() }
        </div>
      </div>
      {this.packUp?<div class="task-type-filter" sytle="margin-top:10px;">
         <div class="task-list-header-nav">
          <div class="task-filter-item">
            <div class="task-font14 task-c7 state">{i18n.t('common.task.taskType')}：</div>
            <div class="list" >
              <div class="list-item task-flex task-ai">
                {[...[{name:i18n.t('common.base.all'),id:undefined}],...this.taskTypes].map((item:any)=>{
                  return (item.id == this.currentTaskType?.id )?<div class="task-nav-create task-c2 task-padding-0" onClick={() => this.changeTaskType(item)}>
                    <div class="actived" title={item.name}>{item.name}</div>
                  </div>: <div class="task-nav-create" onClick={() => this.changeTaskType(item)}>
                    <span title={item.name}>{item.name}</span>
                  </div>
                })}
              </div>
            </div>
          </div>
         </div>
        </div>:null}
      {/* {this.packUp?<div class="task-type-filter">
         <div class="task-list-header-nav">
          <div class="task-filter-item">
            <div class="task-font14 task-c7 state">{i18n.t('common.form.preview.pay.payMethod')}：</div>
            <div class="list" >
              <div class="list-item task-flex task-ai">
                {[...[{label:i18n.t('common.base.all'),value:0, count: allConut}],...this.payMethod].map((item:any)=>{
                  return (item.value == this.currentPayMethod )?<div class="task-nav-create task-c2 task-padding-0" onClick={() => this.changePayMethod(item)}>
                    <div class="actived" title={item.label}>{`${item.label}(${item.count})`}</div>
                  </div>: <div class="task-nav-create" onClick={() => this.changePayMethod(item)}>
                    <span title={item.label}>{`${item.label}(${item.count})`}</span>
                  </div>
                })}
              </div>
            </div>
          </div>
         </div>
        </div>:null} */}
      <div class="pack-up">
        <div onClick={() => this.changePackUpLocal()}>
          {this.packUp?<i class="iconfont icon-Icon_up"></i>:<i class="iconfont icon-more" ></i>}
        </div>
      </div>
   
    </div>
    )
  }

  public changeTaskType(item:any){
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('QUICK_SEARCH', '工单类型'));

    const {name,id}=item
    this.currentTaskType={
      id,
      name,
      templateId:id
    }
    this.initializeTaskTypeAllFields()
    this.refresh()
  }

  public changePayMethod(item:any){
    // @ts-ignore
    this.$track.clickStat(this.$track.formatParams('QUICK_SEARCH', '支付方式'));

    const { value } = item
    this.currentPayMethod = value
    this.initializeTaskTypeAllFields()
    this.refresh()
  }
  
  /**
   * @description: 渲染操作区域容器
   * @return {VNode}
   */ 
  public renderOperationContainer(): VNode {
    return (
      <div ref="tableDoContainer" class='common-list-view__v2 operation-container'>
        <div class='common-list-view-header__v2 task-ai'>
          <div class='common-list-view-header__v2-left task-ai'>
            { this.renderBalanceConfirmRadioGroup() }
            { this.renderBatchBalanceButton() }
          </div>
          <div class='common-list-view-header__v2-right task-ai'>
            { this.renderSubscriptionButton() }
            { checkButtonDisplayed() && (this.renderMoreActionDropdown()) }
            { this.renderSelectColumnsButton() }
          </div>
        </div>
      </div>
    )
  }
  
  /**
   * @description: 渲染工单结算统计容器
   * @return {VNode}
   */  
  private rednerBalanceCountContainer() {
    return (
      <div ref="tableHeaderTypeContainer" class='common-list-section__v2 balance-list-count-container mb_12'>
        { 
          this.rednerBalanceCountNumberItem(
            i18n.t('task.taskTypes.balance.unsettledTaskNum') as string, 
            this.taskBalanceCount?.unBalanceCount,
            BalanceCountMap.unBalanceCount.backgroundColor,
            BalanceCountMap.unBalanceCount.icon
          ) 
        }
        { 
          this.rednerBalanceCountNumberItem(
            i18n.t('task.taskTypes.balance.unsettledFee') as string, 
            this.taskBalanceCount?.unBalanceCost,
            BalanceCountMap.unBalanceCost.backgroundColor,
            BalanceCountMap.unBalanceCost.icon,
            this.taskBalanceCount?.unBalanceCostCurrency || 'CNY'
          ) 
        }
        { 
          this.rednerBalanceCountNumberItem(
            i18n.t('task.taskTypes.balance.lastDaySettledTask', {num: 30}) as string, 
            this.taskBalanceCount?.balanceCountNearlyOneMonth,
            BalanceCountMap.balanceCountNearlyOneMonth.backgroundColor,
            BalanceCountMap.balanceCountNearlyOneMonth.icon
          ) 
        }
        { 
          this.rednerBalanceCountNumberItem(
            i18n.t('task.taskTypes.balance.lastDaySettledFee', {num: 30}) as string, 
            this.taskBalanceCount?.balanceTotalNearlyOneMonth,
            BalanceCountMap.balanceTotalNearlyOneMonth.backgroundColor,
            BalanceCountMap.balanceTotalNearlyOneMonth.icon,
            this.taskBalanceCount?.balanceTotalNearlyOneMonthCurrency || 'CNY'
          ) 
        }
      </div>
    )
  }
  
  /**
   * @description: 渲染其他组件容器
   * @return {VNode}
   */ 
  public renderComponentsContainer(): VNode {
    return (
      <div>
        {/* { this.renderAdvancedSearchPanel() } */
        this.renderAdvancedSearchPanelAllot()}
        { this.renderSelectColumnComponent() }
        { this.renderExportComponent() }
        { this.renderTaskBalanceDialogComponent() }
        { this.renderExportTaskComponent() }
        { this.renderSelectionPanelComponent() }
      </div>
    )
  }
  
  /**
   * @description: 渲染工单结算统计数量项
   * @param {string} text 文字
   * @param {number} num 数量
   * @param {string} icon 图标
   * @return {VNode}
   */  
  private rednerBalanceCountNumberItem(
    text: string, 
    num: number | string | undefined,
    backgroundColor?: string,
    icon: string = '',
    currencyType: string = ''
  ) {
    const value: number | string = fmt_number_fixed2(fmt_number(num, '--'), currencyType)
    
    return (
      <div class='balance-list-count-number-item ml_20 mr_20' style={{ backgroundColor }}>
        <div class='balance-list-count-number-item__content'>
          <div> <h3> { value } </h3> </div>
          <div> { text } </div>
        </div>
        <div class='balance-list-count-number-item__icon'>
          <i class={['iconfont', icon]}></i>
        </div>
      </div>
    )
    
  }
  
  /**
   * @description 渲染审核结算权限提示模块
   * @return {VNode}
   */  
  private renderBalancePermissionContainer(): VNode {
    if(!this.balanceOn) {
      return (
        <div class="balance-permission-tips-block">
          { this.noPermissionText }
        </div> 
      )
    }
    
    return (
      <div></div>
    )
  }

  public refresh() {
    this.loading = true
    setTimeout(async() => {
      // 清空已选中数据
      this.BizTableComponent?.outsideClearSelection()
      this.multipleSelection = []
      // 重新更新列表数据
      await this.search()
      // this.loading = false
    }, 1000)
  }

  /**
   * @des 提供给快捷筛选视图的方法
   */
    public fasterFilterList(keyObj:any){
    try {
      let arr_ = [];
      for(let key in keyObj){
        // All 全部 BalanceConfirm 已结算 BalanceNotConfirm未结算
        let value = keyObj[key]
        if(key == 'balanceConfirmChangedHandler'){
          // 指向function onBalanceConfirmChangedHandler
          let val_ = BalanceConfirmEnum[value]
          this.onBalanceConfirmChangedHandler(val_)
        }
      }
      // this.search();
    } catch (error) {
      console.warn(error, 'fasterFilterList error try catch');
    }
  }
  /**
   * @des 查询是否有查询参数
   */
  public findFastPageData(data?:any){
    return new Promise((resolve:any, reject)=>{
      try {
        let parseData = sessionStorageGet(`bbx-faster-${pageTaskAuditList.type}`);
        if(parseData){
          sessionStorageRemove(`bbx-faster-${pageTaskAuditList.type}`);
        }
        if(!data && !parseData) return resolve()
        const {filterData} = data || JSON.parse(parseData);
        this.fasterFilterList(filterData);
        
      } catch (error) {
        console.warn(error, 'findFastPageData error try catch');
        resolve()
      }
    })
  }
  public computedListPxArray(){
    let tableHeaderTypeContainer_ = this.$refs.tableHeaderTypeContainer?.offsetHeight;
    let padding = [tableHeaderTypeContainer_, 24, 16, 16]
    return padding
  }

  private changePackUpLocal(){
    this.changePackUp()
  }

  /**
   * 高级搜索
   * @param searchModel
   */
   public handleAdvancedSearch(searchModel: any = {}){
    this.advancedSearchModel = searchModel;
    this.search();
  }

  /**
   * 常用字段切换
   * @param {*} fieldName
   * @param {*} isChecked
   */
  public changeCommonUse({fieldName, isChecked}: commonUseItemType){
    const inCommonUseSet = new Set(this.inCommonUse)
    if(isChecked){
      inCommonUseSet.add(fieldName)
    }else {
      inCommonUseSet.delete(fieldName);
    }
    this.inCommonUse = Array.from(inCommonUseSet);
    const storageKey = 'advanced-search-commonUse';
    const storageData = {
      [storageKey]: this.inCommonUse
    }
    storageSet('taskBalanceList', JSON.stringify(storageData))
  }

  /**
   * 恢复常用字段
   */
  public async recoverCommonUse(){
    try {
      const data = JSON.parse(storageGet('taskBalanceList') || '{}');
      const storageKey = 'advanced-search-commonUse';
      this.inCommonUse = data[storageKey] || [];
    } catch (error) {
      console.error('获取常用字段 recoverCommonUse', error);
      return Promise.reject(error)
    }
  }
  
  async mounted() {
    // 恢复常用
    this.recoverCommonUse()
    // 获取初始化数据
    await this.fetchInitData()
    // 获取工单结算列表统计
    this.fetchTaskBalanceCount()
    // 获取结算自定义字段
    await this.fetchBalanceFieldInfo()
    // 获取工单结算列表
    this.findFastPageData().then(()=>{
      this.search();
    });
    
    // 查询工单结算金额
    this.fetchTaskBalancePrice()
    // 查询工单配置
    this.fetchTaskConfig()
    // 初始化工单字段列表
    this.initializeTaskTypeAllFields()
    // [tab_spec]标准化刷新方式
    window.__exports__refresh = async () => {
      setTimeout(() => {
        this.search()
      }, 1000)
    }
    let that_ = this;
    // 监听切换后需要重新计算列表高度 后续可以用activated生命周期替换
    window.addEventListener('message', (event:any)=> {
      const {action, data} = event.data;
      if (action == 'shb.frame.activatedPage'){
        that_.$nextTick(()=> {
          that_.knowTableContainerHeight();
        })
      }
    });
    this.$nextTick(()=> {
      this.knowTableContainerHeight()
      window.onresize = _.debounce(()=>{
        that_.knowTableContainerHeight()
      }, 500)
    })
    
  }
  
  render(h: CreateElement) {
    // 属性列表
    const attrs = this.getAttributes()
    
    return (
      <div {...attrs}>
        { this.rednerBalanceCountContainer() }
        { this.renderHeaderContainer() }
        { this.renderBalancePermissionContainer() }
        { this.renderOperationContainer() }
        { this.renderContentContainer() }
        { this.renderComponentsContainer() }
      </div>
    )
    
  }
  
}

